#include "list.h"
#include <stdlib.h>
#include <string.h>


void list_create(list *l,unsigned int unit,unsigned int length_in_unit)
{
    l->length = 0;
    l->unit = unit;
    l->size = unit*length_in_unit;
    l->pbuffer = malloc(l->size);
}
void list_destroy(list *l)
{
    if(l->pbuffer)
    {
        free(l->pbuffer);
        l->pbuffer = NULL;
    }
    l->length = 0;
    l->size = 0;
}
bool list_get(list *l,unsigned int index,void *e)
{
    if(index < l->length)
    {
        memcpy(e, l->pbuffer+index*l->unit, l->unit);
        return true;
    }
    return false;
}
bool list_set(list *l,unsigned int index,void *e)
{
    if(index < l->length)
    {
        memcpy(l->pbuffer+index*l->unit, e, l->unit);
        return true;
    }    
    return false;
}
bool list_insert(list *l,unsigned int index,void *e)
{
    unsigned int i,j;
    unsigned char *p;
    
    if(index > l->length)
    {
        index = l->length;
    }
    if((l->length+1)*l->unit > l->size)
    {
        unsigned int size = 0;

        size = (l->length * 2)*l->unit;
        if(size < l->size)
        {
            return false;//算术运算溢出
        }
        p = realloc(l->pbuffer, size);
        if(!p)
        {
            return false;//内存不足
        }
        memcpy(p, l->pbuffer, l->length*l->unit);
        free(l->pbuffer);
        l->pbuffer = p;
        l->size = size;
    }
    p = l->pbuffer + l->length*l->unit;
    j = 0;
    for(i=l->length;i>index;i--)
    {
        memcpy(p-j, p-l->unit-j, l->unit);
        j += l->unit;
    }
    memcpy(p-j,e,l->unit);
    l->length++;
    return true;
}
bool list_remove(list *l,unsigned int index,void *e)
{
    unsigned int i,j;
    unsigned char *p;
    
    if(l->length>0)
    {
        if(index >= l->length)
        {
            index = l->length-1;
        }
        p = l->pbuffer + index*l->unit;
        memcpy(e,p,l->unit);
        j = 0;
        for(i=index+1;i<l->length;i++)
        {
            memcpy(p+j, p+j+l->unit, l->unit);
            j += l->unit;
        }
        l->length--;
    }
    return true;
}
unsigned int list_find(list *l,unsigned int index,void *e)
{
    unsigned char *p = l->pbuffer;
    
    while(index<l->length)
    {
        if(memcmp(p,e,l->unit)==0)
        {
            break;
        }
        p+=l->unit;
        index++;
    }
    return index;
} 
void list_traverse(list *l,bool (*visit)(void *))
{
    unsigned char *p = l->pbuffer;
    unsigned int index = 0;
    
    while(index<l->length)
    {
        if(!visit(p))
        {
            break;
        }
        p+=l->unit;
        index++;
    }
}
